# -*- coding: UTF-8 -*-
import hashlib
import hmac
import base64
import time
import uuid
import requests
import json


# 安防平台SDK参考文档地址
# https://open.hikvision.com/docs/docId?version=%2F29c78ef52ca842c7933bd2b8e051e9d0&tagPath=%E6%96%87%E6%A1%A3%E8%AF%B4%E6%98%8E

# 海康安防平台获取资源信息类
class HikVisionAPI:
    def __init__(self, host, port, app_key, app_secret, artemis='artemis', method='POST'):
        """
        初始化类，配置海康威视 API 相关信息
        :param host: 安防平台主机地址
        :param port: 安防平台端口号
        :param app_key: 安防平台合作方的 AppKey
        :param app_secret: 安防平台合作方的 AppSecret
        :param artemis: artemis 服务器路径前缀
        :param method: 请求方法（默认为 POST）
        """
        self.host = host
        self.port = port
        self.app_key = app_key
        self.app_secret = app_secret
        self.artemis = artemis
        self.method = method

    def _generate_signature(self, api):
        """
        生成请求头中的签名信息
        :param api: API 路径
        :return: 包含签名的请求头字典
        """
        timestamp = str(int(round(time.time() * 1000)))  # 当前时间戳（毫秒级）
        nonce = str(uuid.uuid1())  # 生成唯一随机数
        secret = self.app_secret.encode('utf-8')
        # 构造签名消息
        message = f"{self.method}\n*/*\napplication/json\nx-ca-key:{self.app_key}\nx-ca-nonce:{nonce}\nx-ca-timestamp:{timestamp}\n/{self.artemis}{api}".encode(
            'utf-8')
        # 计算 HMAC-SHA256 签名并进行 Base64 编码
        signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest())

        # 构造请求头
        headers = {
            'Accept': '*/*',
            'Content-Type': 'application/json',
            'X-Ca-Key': self.app_key,
            'X-Ca-Signature': signature,
            'X-Ca-timestamp': timestamp,
            'X-Ca-nonce': nonce,
            'X-Ca-Signature-Headers': 'x-ca-key,x-ca-nonce,x-ca-timestamp',
        }
        return headers

    def _post(self, api, payload):
        """
        向 HikVision API 发起 POST 请求
        :param api: API 路径
        :param payload: 请求体参数
        :return: API 返回的 JSON 数据
        """
        url = f"{self.host}:{self.port}/{self.artemis}{api}"  # 构造完整 URL
        headers = self._generate_signature(api)  # 获取带签名的请求头
        response = requests.post(url, headers=headers, json=payload, verify=False, timeout=5)  # 发起 POST 请求
        return response.json()  # 返回 JSON 数据

    def get_video_area(self, page_no=1, page_size=1000, resource_type='region'):
        """
        获取视频区域信息
        :param page_no: 页码（默认第 1 页）
        :param page_size: 每页记录数（默认 1000 条）
        :param resource_type: 资源类型（默认 "region"）
        :return: 区域列表数据
        """
        api = '/api/irds/v2/region/nodesByParams'
        payload = {
            "pageNo": page_no,
            "pageSize": page_size,
            "resourceType": resource_type,
        }
        return self._post(api, payload).get('data', {}).get('list', [])

    def get_video_area_info(self, code, page_no=1, page_size=1000):
        """
        获取指定区域的子资源信息
        :param code: 区域编号
        :param page_no: 页码（默认第 1 页）

        :param page_size: 每页记录数（默认 1000 条）
        :return: 子资源列表数据
        """
        api = '/api/irds/v2/resource/subResources'
        payload = {
            "regionIndexCode": code,
            "pageNo": page_no,
            "authCodes": ["view"],
            "pageSize": page_size,
            "cascadeFlag": 0,
            "resourceType": "camera",
        }
        return self._post(api, payload).get('data', {}).get('list', [])

    def get_rtsp_url(self, code):
        """
        获取带有效期的 RTSP URL
        :param code: 资源编号
        :return: RTSP URL（字符串）
        """
        api = '/api/vnsc/mls/v1/preview/openApi/getPreviewParam'
        payload = {
            "indexCode": code,
            "transmode": 1,
            "streamType": 0,
            "protocol": "rtsp",
            "expireTime": -1,
            "expand": "streamform=rtp",

        }
        return self._post(api, payload).get('data', {}).get('url', None)

    def get_video_area_vcr_info(self, resource_index_codes):
        """
        根据资源索引编号获取录像机信息
        :param resource_index_codes: 资源索引编号列表
        :return: 录像机信息数据
        """
        api = '/api/resource/v1/resource/indexCodes/search'
        payload = {
            "resourceType": "encodeDevice",
            "resourceIndexCodes": resource_index_codes,
        }
        return self._post(api, payload).get('data', {})


# # 使用类调用示例
# if __name__ == "__main__":
#     pass
#
#     # 实例化 配置相关参数
#     hik_api = HikVisionAPI(
#         # host='https://192.168.139.246',
#         host='https://76.10.2.54',
#         port='443',
#         # app_key='24481068',
#         app_key='24073371',
#         # app_secret='wTdNalUIHRlN5ZknxWzc'
#         app_secret='DvfSrDHRXrsEwDe60V5v'
#     )
#
#     # 获取视频区域信息
#     video_areas = hik_api.get_video_area()
#     # print("视频区域信息:", video_areas)
#
#     for i in video_areas:
#         print(i)
#
#     # 获取区域子设备信息
#     region_code = 'e8a52220-e095-4a46-ae7f-e6b0a0337356'
#     sub_resources = hik_api.get_video_area_info(region_code)
#
#
#     # 判断当类型为列表的时候
#     if isinstance(sub_resources, list):
#         print("sub_resources 是列表类型")
#         print(sub_resources)
#
#     # 判断当类型为 dict 的时候
#     elif isinstance(sub_resources, dict):
#         print("sub_resources 是字典类型")
#         sub_resources = sub_resources['data']['list']
#         print(sub_resources)
#
#     else:
#         print(f"sub_resources 是 {type(sub_resources).__name__} 类型，暂不处理")
#
#     print(type(sub_resources), len(sub_resources))


    # print("子设备信息:", sub_resources)
    #
    # # 获取 时效性 RTSP URL
    # rtsp_url = hik_api.get_rtsp_url('d2e884e4b9384065957721d11d711932')
    # print("RTSP URL:", rtsp_url)
    #
    # # 获取录像机信息(传入参数为监控点资源信息parent_Indexcode)
    # vcr_info = hik_api.get_video_area_vcr_info(['431e5596e4d641a9b7bbe7d084c42688'])
    # print("录像机信息:", vcr_info)

